/**
 * Copyright (c) 2012 Nokia Corporation. 
 */

package com.nokia.example.tictactoe.engine;

import java.util.Random;


/**
 * Basic game manager for single/two player game on a single device.
 */
public class BasicGameManager extends AbstractGameManager {
	// Members
	protected static AbstractGameManager _instance = null; // Singleton instance
	private GameModel _gameModel = null;
	private ITicTacToeAI _ai = null;
	
	/** 
	 * @param gameModel
	 * @return The singleton instance of BasicGameManager.
	 */
	public static AbstractGameManager instance(GameModel gameModel) {
		if (_instance == null) {
			_instance = new BasicGameManager(gameModel);
		}
		
		return _instance;
	}
	
	/**
	 * Releases the singleton instance.
	 */
	public void release() {
		_instance = null;
	}
	
	/**
	 * Constructor.
	 * @param gameModel
	 */
	private BasicGameManager(GameModel gameModel) {
		if (gameModel == null) {
			throw new IllegalArgumentException();
		}
		
		_gameModel = gameModel;
		_ai = new MinimaxAI(1);
	}
	
	/**
	 * From AbstractGameManager.
	 */
	public void startGame() {
		System.out.println("BasicGameManager::startGame()");
		_gameOngoing = true;
		_gameModel.initModel();
		
		Random random  = new Random();
		random.setSeed(System.currentTimeMillis());
		
		if (random.nextInt(2) == 0) {
			_gameModel.setPlayerMark(GameModel.MARK_X);
			_gameModel.setWhoseTurn(GameModel.MARK_X);
		}
		else {
			_gameModel.setPlayerMark(GameModel.MARK_O);
			_gameModel.setWhoseTurn(GameModel.MARK_X);
			
			// Put the first mark at random
			_gameModel.setMark(random.nextInt(_gameModel.gridSizeSquared()),
							   random.nextInt(_gameModel.gridSizeSquared()),
							   GameModel.MARK_X);
			_gameModel.switchTurns();
		}
	}

	/**
	 * From AbstractGameManager.
	 */
	public void endGame() {
		onGameOver();
	}
	
	/**
	 * From AbstractGameManager.
	 */
	public void onSquarePressed(int x, int y) {
		System.out.println("BasicGameManager::onSquarePressed(): ["
				+ x + ", " + y + "]");
		int playerMark = _gameModel.playerMark();
		
		if (playerMark == GameModel.MARK_EMPTY
				|| playerMark != _gameModel.whoseTurn()
				|| !gameOngoing())
		{
			System.out.println("BasicGameManager::onSquarePressed(): Not your turn or game is not ongoing ("
					+ playerMark + ", " + _gameModel.whoseTurn() + ", " + gameOngoing() + ")!");
			return;
		}
		
		try {
			if (_gameModel.markAt(x, y) == GameModel.MARK_EMPTY) {
				_gameModel.setMark(x, y, playerMark);
				
				// Switch player mark and turn
				/*if (playerMark == GameModel.MARK_X) {
					playerMark = GameModel.MARK_O;
				}
				else {
					playerMark = GameModel.MARK_X;
				}
				
				_gameModel.setPlayerMark(playerMark);
				_gameModel.setWhoseTurn(playerMark);*/
				
				if (gameOngoing()) {
					_gameModel.switchTurns();
					final int aiMark = (playerMark == GameModel.MARK_X)
							? GameModel.MARK_O : GameModel.MARK_X; 
					int[] markXY = _ai.nextMove(_gameModel, aiMark);
					_gameModel.setMark(markXY[0], markXY[1], aiMark);
					_gameModel.switchTurns();
				}
			}
		}
		catch (IllegalArgumentException e) {}
	}

	/**
	 * From AbstractGameManager.
	 */
	public void onGameOver() {
		_gameOngoing = false;
	}
	
	/**
	 * From AbstractGameManager.
	 */
	public int type() {
		return AbstractGameManager.BASIC;
	}	
}
